;;org 0x7c00

bits 16

org 0

jmp 0x7c0:start
nop

bpb:
db "MSWIN4.1"
db 0
db 2
db 2
dw 6
db 2
db 0
db 2
db 0xF0
db 0X0A
db 0xF0
dw 4
dw 18
dw 2
dd 6
dd 0

ebpb:
dw 0
db 0x28
dd 0x12345678
db "NEMESIS OS "
db "FAT16   "

msg db "Welcome to NemesisOS!", 13, 10, 0
msg1 db "Loading second stage...", 13, 10, 0
msg2 db "Jumping...", 13, 10, 0

Print:
lodsb
or al,al
jz PrintDone
mov ah,0eh
int 10h
jmp Print
PrintDone:
ret

start:

;;xor ax,ax

cli
mov ax, 0x7c0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov sp, 0x0 ;0x7c0:0
sti

mov si,msg
call Print


mov si,msg1
call Print

xor ecx, ecx

mov ah,2h
mov al,3h
xor ch,ch
mov cl,2h
xor dx,dx
mov bx,500h

int 13h

mov si,msg2
call Print

jmp 0x500

times 510 - ($ - $$) db 0

dw 0xAA55

;;org 0
org 0x8100

bits 16

;we are at linear 8100 (0x810:0)

;;jmp short start
jmp start

msg3 db "Second stage loaded", 13, 10, 0		;0x50:2

Print:
lodsb
or al,al
jz PrintDone
mov ah,0eh
int 10h
jmp Print
PrintDone:
ret



;*******************************************
; Global Descriptor Table (GDT)
;*******************************************
 ;0x8124

gdt_data: 
	dd 0 				; null descriptor
	dd 0 
 
; gdt code:				; code descriptor
	dw 0FFFFh 			; limit low
	dw 0 				; base low
	db 0 				; base middle
	db 10011010b 			; access
	db 11001111b 			; granularity
	db 0 				; base high
 
; gdt data:				; data descriptor
	dw 0FFFFh 			; limit low (Same as code)
	dw 0 				; base low
	db 0 				; base middle
	db 10010010b 			; access
	db 11001111b 			; granularity
	db 0				; base high
 
end_of_gdt:

toc: 
	dw end_of_gdt - gdt_data - 1 	; limit (Size of GDT)
	dd gdt_data 			; base of GDT
;;	dd gdt_data+0x8100 			; base of GDT

;base=0x61 limit=0x17

InstallGDT:
 
	cli				; clear interrupts
;;	pusha				; save registers
	lgdt 	[toc]			; load GDT into GDTR
	sti				; enable interrupts
;;	popa				; restore registers
	ret				; All done!
 

start:

cli
mov ax, 0x0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;;mov ax, 0x9000
mov ss, ax
mov sp, 0 ;;;xFFFF ;Stack goes from 0x9000 to 0xFFFF
sti

mov si,msg3
call Print

call InstallGDT

cli

mov eax,cr0
or eax,1
mov cr0,eax

;;jmp 08h:stage3+0x8100
jmp 08h:stage3

bits 32

enable_A20:

call a20wait
mov al,0XAD
out 0x64,al

call a20wait
mov al,0xD0
out 0x64,al

call a20wait2
in al,0x60
push eax

call a20wait
mov al,0xD1
out 0x64,al

call a20wait
pop eax
or al,2
out 0x60,al

call a20wait
mov al,0xAE
out 0x64,al

call a20wait
ret

a20wait:

in al,0x64
test al,2
jnz a20wait
ret

a20wait2:

in al,0x64
test al,1
jz a20wait2
ret

stage3:

mov ax,0x10
mov ds,ax
mov ss,ax
mov es,ax
mov esp,90000h

call enable_A20

jmp stage4

msg4 db "Printing initialized...",0

idt_start:

dw interrupt_0 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_1
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_2 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_3 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_4 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_5
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_6
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_7
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_8
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_9
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_A
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_B
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_C
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_D
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_E
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_F
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_10 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_11
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_12 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_13 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_14 
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_15
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_16
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_17
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_18
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_19
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_1A
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_1B
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_1C
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_1D
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_1E
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_1F
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_20
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_21
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_22
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_23
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_24
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_25
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_26
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_27
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_28
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_29
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_2A
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_2B
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_2C
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_2D
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_2E
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_2F
dw 0x8
db 0
db 0x8F
dw 0

dw interrupt_30
dw 0x8
db 0
db 0x8E
dw 0

dw interrupt_31
dw 0x8
db 0
db 0x8E
dw 0
idt_end:
idt_toc:
dw idt_end - idt_start - 1
dd idt_start

interrupt_0:
hlt
interrupt_1:
hlt
interrupt_2:
hlt
interrupt_3:
hlt
interrupt_4:
hlt
interrupt_5:
hlt
interrupt_6:
hlt
interrupt_7:
hlt
interrupt_8:
hlt
interrupt_9:
hlt
interrupt_A:
hlt
interrupt_B:
hlt
interrupt_C:
hlt
interrupt_D:
hlt
interrupt_E:
hlt
interrupt_F:
hlt
interrupt_10:
hlt
interrupt_11:
hlt
interrupt_12:
hlt
interrupt_13:
hlt
interrupt_14:
hlt
interrupt_15:
hlt
interrupt_16:
hlt
interrupt_17:
hlt
interrupt_18:
hlt
interrupt_19:
hlt
interrupt_1A:
hlt
interrupt_1B:
hlt
interrupt_1C:
hlt
interrupt_1D:
hlt
interrupt_1E:
hlt
interrupt_1F:
hlt
interrupt_20:
mov al,0x20
out 0x20,al
iret
interrupt_21:
mov al,0x20
out 0x20,al
iret
interrupt_22:
mov al,0x20
out 0x20,al
iret
interrupt_23:
mov al,0x20
out 0x20,al
iret
interrupt_24:
mov al,0x20
out 0x20,al
iret
interrupt_25:
mov al,0x20
out 0x20,al
iret
interrupt_26:
mov al,8
call DMASendCommand
call DMASendCommand
call DMASendCommand
call DMASendCommand
mov al,0x20
out 0x20,al
iret
interrupt_27:
mov al,0x20
out 0x20,al
iret
interrupt_28:
mov al,0x20
out 0x20,al
iret
interrupt_29:
mov al,0x20
out 0xA0,al
iret
interrupt_2A:
mov al,0x20
out 0xA0,al
iret
interrupt_2B:
mov al,0x20
out 0xA0,al
iret
interrupt_2C:
mov al,0x20
out 0xA0,al
iret
interrupt_2D:
mov al,0x20
out 0xA0,al
iret
interrupt_2E:
mov al,0x20
out 0xA0,al
iret
interrupt_2F:
mov al,0x20
out 0xA0,al
iret
interrupt_30:
mov ecx,0xB8000
add ecx,ebx
mov [ecx],al
inc ecx
mov [ecx],ah
iret
interrupt_31:
mov ecx,0xB8000
loop:
cmp ecx,0xB8FA0
jz int31done
mov [ecx],al
inc ecx
mov [ecx],ah
inc ecx
jmp loop
int31done:
iret

print:
lodsb
or al,al
jz printDone
add ebx,2
int 30h
jmp print

printDone:
ret

DMARead:
mov al,6
out 0x0a,al
mov al,0x56
out 0x0b,al
mov al,2
out 0x0a,al
ret

DMAWrite:
mov al,6
out 0x0a,al
mov al,0x5a
out 0x0b,al
mov al,2
out 0x0a,al
ret

DMASendCommand:
DMALoop:
mov dx,0x3F4
in al,dx
bt ax,4
jc DMALoop
mov dx,0X3f5
out dx,al
DMALoop1:
mov dx,0x3F4
in al,dx
bt ax,4
jc DMALoop1
ret

stage4:

lidt [idt_toc]

mov al,0x41
xor ah,ah
int 31h

mov esi, msg4	;esi=0xdd its at offset 0x34...
mov ah,0x0f
mov ebx,0xfffffffe
call print

mov al,0x11
out 0x20,al

out 0xA0,al

mov al,0x20
out 0x21,al

mov al,0x28
out 0xA1,al

mov al,0x4
out 0x21,al

mov al,0x2
out 0xA1,al

mov al,1

out 0x21,al
out 0xA1,al

mov dx,0x2E9C

mov al,0x36
out 0x43,al

mov ax,dx
out 0x40,al
xchg ah,al
out 0x40,al

in al,0x21
and al,0xFE
out 0x21,al

sti

mov al,6
out 0x0a,al
mov al,255
out 0xd8,al
mov al,0
out 0x04,al
mov al,16
out 0x04,al
mov al,255
out 0xd8,al
out 0x05,al
mov al,0x23
out 0x05,al
mov al,0
out 0x80,al
mov al,0x02
out 0x0a,al

mov al,0
mov dx,0x3f2
out dx,al
mov al,0xC
out dx,al

mov al,0
mov dx,0x3f7
out dx,al

mov al,3
call DMASendCommand
mov al,0x30
call DMASendCommand
mov al,0x21
call DMASendCommand

mov dx,0x3f2
in al,dx
or al,0x1C
out dx,al

mov al,7
call DMASendCommand

xor al,al
call DMASendCommand

loop1:
mov dx,0x3f4
in al,dx
bt ax,4
jc loop1

mov al,8
call DMASendCommand

cli
hlt
